/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include <stdafx.h>

#include "系统平台.h"

#include <Windows.h>
#include <字符串转换.h>

#include "file_文件名数据.h"




std::u16string f_sys_get剪切板文本() {
	std::u16string text;

	if (OpenClipboard(nullptr)) {
		if (IsClipboardFormatAvailable(CF_TEXT)) {

			auto 剪切板 = GetClipboardData(CF_TEXT);
			
			//const wchar_t* lpwstr = (const wchar_t*)GlobalLock(剪切板);
			//if (lpwstr) {
			//	std::wstring wstr(lpwstr);
			//	GlobalUnlock(剪切板);
			//	CloseClipboard();
			//	return wstr;
			//}

			auto pBuf = (int8*)GlobalLock(剪切板);
			std::string t(pBuf);
			t += '\0';

			GlobalUnlock(剪切板);

			
			//text = f_StringToWString(t, "gbk");
			//text = f_StringToWString(t, "utf-8");
			text = f_str_GBKToUTF16(t);
			if (!text.empty() && text.back() == '\0') {
				text.pop_back();
			}

			CloseClipboard();
		}
	}

	return text;
}


std::u16string f_sys_get剪切板u16Str() {
	std::u16string utf16string;

	if (OpenClipboard(NULL)) {
		HANDLE hData = GetClipboardData(CF_TEXT);
		if (hData != NULL) {
			const char* gbkText = static_cast<const char*>(GlobalLock(hData));
			if (gbkText) {
				// 计算转换为UTF-16所需的缓冲区大小
				int utf16Length = MultiByteToWideChar(CP_ACP, 0, gbkText, -1, NULL, 0);
				if (utf16Length > 0) {
					// 将GBK编码转换为UTF-16编码
					std::wstring utf16WString;
					utf16WString.resize(utf16Length - 1); // -1 为了去掉结尾的空字符
					MultiByteToWideChar(CP_ACP, 0, gbkText, -1, &utf16WString[0], utf16Length);

					// 将UTF-16编码转换为UTF-8编码
					std::string utf8String;
					utf8String.resize(utf16Length * 3); // 最坏情况下，每个UTF-16字符转换为3个UTF-8字符
					WideCharToMultiByte(CP_UTF8, 0, utf16WString.c_str(), -1, &utf8String[0], utf8String.capacity(), NULL, NULL);

					// 将UTF-8编码的std::string转换为std::u16string
					for (unsigned char ch : utf8String) {
						utf16string.push_back(static_cast<char16_t>(ch));
					}
				}
			}
			GlobalUnlock(hData);
		}
		CloseClipboard();
	}

	return utf16string;
}

void f_sys_写到剪切板(const std::string& data) {
	uint64 dwLength = data.size();	
	HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1);	
	LPBYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory);	


	auto 转码 = f_String转码(data, "gbk");
	auto* pData = (uint8*)转码.data();
	
	for (int32 i = 0; i < dwLength; ++i) *lpGlobalMemory++ = pData[i];
	//for (int32 i = 0; i < dwLength; ++i) *lpGlobalMemory++ = data[i];

	GlobalUnlock(hGlobalMemory); // 锁定内存块解锁
	

	OpenClipboard(nullptr); // 打开剪贴板
	EmptyClipboard(); // 清空剪贴板
	SetClipboardData(CF_TEXT, hGlobalMemory); // 将内存中的数据放置到剪贴板
	CloseClipboard(); // 关闭剪贴板
}

std::filesystem::path f_sys_get字体文件目录() {
	WCHAR buffer[MAX_PATH];
	GetWindowsDirectory(buffer, MAX_PATH);

	std::wstring p = buffer;
	p += L"/Fonts";

	return std::filesystem::path(p);
}

std::filesystem::path f_sys_get程序目录() {
	WCHAR tszExePath[MAX_PATH];
	DWORD dwSize = GetModuleFileName(NULL, tszExePath, MAX_PATH);

	
	//std::wcout << path << "\n";
	std::wstring t(tszExePath);
	std::replace(t.begin(), t.end(), '\\', '/');
	
	auto path = std::filesystem::path(t);
	//path = path.string();
	//path.parent_path();
	return path.parent_path();
}


uint64 f_sys_加载代码(std::string path, E_JIT方式 方式) {
	switch (方式) {
		case E_JIT方式::e_jit_llvm: {
			//uint64 ee = (uint64)f_llvm_创建程序集(path);
			return (uint64)0;
		}
		case E_JIT方式::e_jit_dll: {
			auto* ee = LoadLibraryA(path.c_str());

			//auto pdb = f_file_替换后缀(path, ".pdb");
			//WIN32_FIND_DATAA findFileData;
			//HANDLE findHandle = FindFirstFileA(pdb.c_str(), &findFileData);
			//
			//if (findHandle != INVALID_HANDLE_VALUE) {
			//	UnlockFile(findHandle, 0, 0, 0, 0);
			//
			//	// 结束搜索
			//	FindClose(findHandle);
			//}
			//else {
			//	// 处理错误
			//	DWORD dwError = GetLastError();
			//	printf("FindFirstFile failed with error %lu\n", dwError);
			//}

			return (uint64)ee;
		}
	}
	return 0;
}

uint64 f_sys_取函数指针(uint64 模块, std::string 函数名称, E_JIT方式 方式) {
	if (函数名称.empty()) return 0;

	switch (方式) {
		case E_JIT方式::e_jit_llvm: {
			return 0;
		}
		case E_JIT方式::e_jit_dll: {
			return (uint64)GetProcAddress((HMODULE)模块, 函数名称.c_str());
		}
	}

	return 0;
}

